package cn.com.controller.frontController;

import cn.com.Enum.OrderStatus;
import cn.com.Enum.SessionAttr;
import cn.com.Enum.UserAuth;
import cn.com.annotation.Auth;
import cn.com.constant.Code;
import cn.com.db.model.Address;
import cn.com.db.model.DiyOrder;
import cn.com.db.model.DiyWork;
import cn.com.db.model.OrderItem;
import cn.com.db.model.Store;
import cn.com.db.model.User;
import cn.com.db.model.WxDiyPayResult;
import cn.com.db.model.WxDiyRefundResult;
import cn.com.db.model.WxPayResult;
import cn.com.db.model.WxRefundResult;
import cn.com.db.service.AddressService;
import cn.com.db.service.DiyOrderService;
import cn.com.db.service.DiyWorkService;
import cn.com.db.service.StoreService;
import cn.com.db.service.UserService;
import cn.com.db.service.WxDiyPayResultService;
import cn.com.db.service.WxDiyRefundResultService;
import cn.com.util.*;
import cn.com.wxUtil.SendTemplateMessageUtil;
import cn.com.wxUtil.XMLUtil;
import cn.com.wxUtil.wxConstant;
import cn.com.wxUtil.refundUtil.RefundConstant;
import cn.com.wxUtil.refundUtil.WeiXinAtcion;
import cn.com.wxUtil.template.TemplateData;
import cn.com.wxUtil.template.WechatTemplate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import org.jdom.JDOMException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA. User: yue Date: 2018-03-31 Time: 18:24
 * Description:
 */
@Auth(UserAuth.USER)
@RestController
@RequestMapping("front/diyorder")
public class DiyOrderController {

	Logger logger = LoggerFactory.getLogger(DiyOrderController.class);

	@Autowired
	StoreService storeService;
	@Autowired
	AddressService addressService;
	@Autowired
	DiyWorkService diyWorkService;
	@Autowired
	DiyOrderService diyOrderService;
	@Autowired
	UserService userService;
	@Autowired
	WxDiyRefundResultService wxDiyRefundResultService;
	@Autowired
	WxDiyPayResultService wxDiyPayResultService;

	@RequestMapping(value = "/placeOrder", method = RequestMethod.POST)
	public String placeOrder(HttpServletRequest request, @RequestParam("diyGoodsId") String diyGoodsId,
			@RequestParam("count") Integer count, @RequestParam("addressId") String addressId,
			@RequestParam("price") BigDecimal price, @RequestParam("freight") BigDecimal freight,
			@RequestParam("remark") String remark) {
		DataResult dataResult = new DataResult();
		String userAuthingId = (String) SessionUtil.getAttr(request, SessionAttr.USERAUTHINGID);
		DiyWork diyWork = diyWorkService.getDiyWorkById(diyGoodsId);
		if (diyWork == null) {
			dataResult.setCode(Code.NOT_FOUND);
			dataResult.setMessage("diy蛋糕不存在");
			return JsonUtil.toJsonString(dataResult);
		}
		Store store = storeService.getStoreById(diyWork.getStore());
		Address address = addressService.getAddressById(addressId);
		if (!storeService.isAlive(store.getId())) {
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("商家不处于接单状态");
			return JsonUtil.toJsonString(dataResult);
		}
		if (address == null) {
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("收货地址不存在");
			return JsonUtil.toJsonString(dataResult);
		}
		BigDecimal diyPrice = diyWorkService.countDiyWorkPrice(diyGoodsId);
		if (!diyPrice.multiply(new BigDecimal(count)).equals(price)) {
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("价格变化");
			return JsonUtil.toJsonString(dataResult);
		}
		DiyOrder order = new DiyOrder();
		order.setId(UidUtil.createUUID());
		order.setUser(userAuthingId);
		order.setStore(store.getId());
		order.setSeller(store.getSeller());
		order.setDiyWork(diyWork);
		order.setProvince(address.getProvince());
		order.setCity(address.getCity());
		order.setDistrict(address.getDistrict());
		order.setDetail(address.getDetail());
		order.setRecipient(address.getName());
		order.setPhone(address.getPhone());
		order.setPrice(diyPrice.multiply(new BigDecimal(count)));
		order.setFreight(store.getFreight());
		order.setStatus(OrderStatus.WAIT_PAY.getStatus());
		order.setCount(count);
		order.setRemark(remark);
		order.setCreated_at(TimeUtil.getNowTimestamp());
		order.setUpdated_at(TimeUtil.getNowTimestamp());
		try {
			order.countTotalPrice();
		} catch (Exception e) {
			logger.warn("用户id为:{}的用户提交的订单由于无法计算出总价而无法生成;{}", userAuthingId, JSON.toJSONString(order));
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("订单生成失败,无法计算出总价!");
			JsonUtil.toJsonString(dataResult);
		}
		diyOrderService.createDiyOrder(order);
		dataResult.setCode(Code.SUCCESS);
		dataResult.setData(order.getId());
		dataResult.setMessage("提交diy订单成功");
		return JsonUtil.toJsonString(dataResult);
	}

	@RequestMapping(value = "/viewOrder/{id}", method = RequestMethod.GET)
	public String placeOrder(HttpServletRequest request, @PathVariable("id") String id) {
		DataResult dataResult = new DataResult();
		DiyOrder diyOrder = diyOrderService.getDiyOrderById(id);
		if (diyOrder == null) {
			dataResult.setCode(Code.NOT_FOUND);
			dataResult.setMessage("订单不存在");
			return JsonUtil.toJsonString(dataResult);
		}
		dataResult.setCode(Code.SUCCESS);
		dataResult.setMessage("返回成功");
		dataResult.setData(diyOrder);
		return JsonUtil.toJsonString(dataResult);
	}

	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
	public String viewOrder(@PathVariable("id") String id) {
		DataResult dataResult = new DataResult();
		DiyOrder order = diyOrderService.getDiyOrderById(id);
		if (order == null) {
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("订单不存在");
			return JsonUtil.toJsonString(dataResult);
		}
		dataResult.setData(order);
		dataResult.setCode(Code.SUCCESS);
		dataResult.setMessage("返回成功");
		return JsonUtil.toJsonString(dataResult);
	}

	@RequestMapping(value = "/cancel", method = RequestMethod.POST)
	public String cancel(HttpServletRequest request, @RequestParam("orderId") String orderId) throws Exception {
		DataResult dataResult = new DataResult();
		String userAuthingId = (String) SessionUtil.getAttr(request, SessionAttr.USERAUTHINGID);
		DiyOrder order = diyOrderService.getDiyOrderById(orderId);
		if (order == null) {
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("订单不存在");
			return JsonUtil.toJsonString(dataResult);
		}
//		if (!order.getUser().equals(userAuthingId)) {
//			dataResult.setCode(Code.FORBIDDEN);
//			dataResult.setMessage("操作失败");
//			return JsonUtil.toJsonString(dataResult);
//		}
		if (!order.getStatus().equals(OrderStatus.WAIT_ORDERS.getStatus())) {
			dataResult.setCode(Code.FORBIDDEN);
			dataResult.setMessage("当前状态无法取消订单");
			return JsonUtil.toJsonString(dataResult);
		}
	

		/************** 退款 ********************/
		WxDiyPayResult payResult = wxDiyPayResultService.getPayResultByOrderId(orderId);
		if (payResult == null) {
			dataResult.setCode(Code.FORBIDDEN);
			dataResult.setMessage("该订单未支付成功,请重新支付");
			return JsonUtil.toJsonString(dataResult);
		}
		String out_trade_no = payResult.getId(); // 退款订单
		String xmlWxInfo = payResult.getWx_meta_info();
		Map xmlMap = XMLUtil.doXMLParse(xmlWxInfo);
		String total_fee = (String) xmlMap.get("cash_fee");
		BigDecimal all_total_fee = new BigDecimal(total_fee); // 订单金额
		BigDecimal refund_fee = order.getTotalPrice().movePointRight(2); // 退款金额
		String appid = wxConstant.APPID; // 微信小程序--》“开发者ID”
		String mch_id = wxConstant.MCH_ID; // 商户号，将该值赋值给partner
		String key = wxConstant.PAY_KEY; // 微信支付商户平台登录）--》“API安全”--》“API密钥”--“设置密钥”（设置之后的那个值就是partnerkey，32位）

		Map<String, String> refundmap = WeiXinAtcion.wechatRefund(mch_id, appid, key, out_trade_no, all_total_fee,
				refund_fee);

		String resultJson = JSON.toJSONString(refundmap);
		// 退款之后业务逻辑 : 修改订单状态,新建数据库表
		WxDiyRefundResult wxRefundResult = new WxDiyRefundResult();
			if (refundmap.get("return_code").equals("SUCCESS")) {
				if (refundmap.get("result_code").equals("FAIL")) {
					// 失败
			//		dataResult.setData(refundmap.get("err_code_des"));
					wxRefundResult.setId(UidUtil.createUUID());
					wxRefundResult.setOrder(orderId);
					wxRefundResult.setSeller(order.getSeller());
					wxRefundResult.setUser(order.getUser());
					wxRefundResult.setStore(order.getStore());
					wxRefundResult.setWx_meta_info(resultJson); // 存的json
					wxRefundResult.setType(RefundConstant.DIYTYPE);
					wxRefundResult.setResult(false);
					wxRefundResult.setCreated_at(TimeUtil.getNowTimestamp());
					wxRefundResult.setUpdated_at(TimeUtil.getNowTimestamp());
					wxDiyRefundResultService.createDiyRefundResult(wxRefundResult);
					dataResult.setCode(Code.REFUND_FAIL);
					dataResult.setMessage("「取消订单失败，原因：退款失败，请稍候再试」");
					return JsonUtil.toJsonString(dataResult);
				} else {
					
					wxRefundResult.setId(UidUtil.createUUID());
					wxRefundResult.setOrder(orderId);
					wxRefundResult.setSeller(order.getSeller());
					wxRefundResult.setUser(order.getUser());
					wxRefundResult.setStore(order.getStore());
					wxRefundResult.setWx_meta_info(resultJson); // 存的json
					wxRefundResult.setType(RefundConstant.DIYTYPE);
					wxRefundResult.setResult(true);
					wxRefundResult.setCreated_at(TimeUtil.getNowTimestamp());
					wxRefundResult.setUpdated_at(TimeUtil.getNowTimestamp());
					wxDiyRefundResultService.createDiyRefundResult(wxRefundResult);
				}
			} else {
				// 失败
			//	dataResult.setData(refundmap.get("return_ms"));
				wxRefundResult.setId(UidUtil.createUUID());
				wxRefundResult.setOrder(orderId);
				wxRefundResult.setSeller(order.getSeller());
				wxRefundResult.setUser(order.getUser());
				wxRefundResult.setStore(order.getStore());
				wxRefundResult.setWx_meta_info(resultJson); // 存的json
				wxRefundResult.setType(RefundConstant.DIYTYPE);
				wxRefundResult.setResult(false);
				wxRefundResult.setCreated_at(TimeUtil.getNowTimestamp());
				wxRefundResult.setUpdated_at(TimeUtil.getNowTimestamp());
				wxDiyRefundResultService.createDiyRefundResult(wxRefundResult);
				dataResult.setCode(Code.REFUND_FAIL);
				dataResult.setMessage("「取消订单失败，原因：退款失败，请稍候再试」");
				return JsonUtil.toJsonString(dataResult);
			}
		/**********************************/
		diyOrderService.updateDiyOrderStatus(orderId, OrderStatus.CANCEL.getStatus());

		dataResult.setCode(Code.SUCCESS);
		dataResult.setMessage("取消订单成功");
		return JsonUtil.toJsonString(dataResult);
	}

	@RequestMapping(value = "/confirm", method = RequestMethod.POST)
	public String confirm(HttpServletRequest request, @RequestParam("orderId") String orderId) {
		DataResult dataResult = new DataResult();
		String userAuthingId = (String) SessionUtil.getAttr(request, SessionAttr.USERAUTHINGID);
		DiyOrder order = diyOrderService.getDiyOrderById(orderId);
		if (order == null) {
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("订单不存在");
			return JsonUtil.toJsonString(dataResult);
		}
		if (!order.getUser().equals(userAuthingId)) {
			dataResult.setCode(Code.FORBIDDEN);
			dataResult.setMessage("操作失败");
			return JsonUtil.toJsonString(dataResult);
		}
		if (!order.getStatus().equals(OrderStatus.TRANING.getStatus())) {
			dataResult.setCode(Code.FORBIDDEN);
			dataResult.setMessage("当前状态无法确认订单");
			return JsonUtil.toJsonString(dataResult);
		}
		diyOrderService.updateDiyOrderStatus(orderId, OrderStatus.COMPLETE.getStatus());
		/******************* 发送模板消息 ************************/
			WechatTemplate w = new WechatTemplate();
			String userId = order.getUser();
			User user = userService.getUserAuthingId(userId);
			String openid = user.getOpenId();
			w.setTouser(openid);
			String prepayId = wxDiyPayResultService.getPrepayIdByOrderId(orderId);
			w.setForm_id(prepayId);
			String page = "/pages/my";
			w.setPage(page);
			w.setTemplate_id(wxConstant.TEMPLATE_ID_RECEIPTGOODS);
			LinkedHashMap<String, TemplateData> map = new LinkedHashMap<>();
			TemplateData t1 = new TemplateData();
			String time = order.getUpdated_at().toString();
			time = time.substring(0, time.indexOf("."));
			t1.setValue("您已确认收货");
			t1.setColor("#000000");
			map.put("keyword1", t1);
			TemplateData t2 = new TemplateData();
			t2.setValue(order.getId());
			t2.setColor("#000000");
			map.put("keyword2", t2);
			TemplateData t3 = new TemplateData();
			t3.setValue(order.getDiyWork().getName());   // 商品详情
			t3.setColor("#000000");
			map.put("keyword3", t3);
			TemplateData t5 = new TemplateData();
			t5.setValue(order.getPhone());
			t5.setColor("#000000");
			map.put("keyword4", t5);
			TemplateData t6 = new TemplateData();
			Address address = addressService.getUserDefAddress(userId);
			t6.setValue(address.getName());
			t6.setColor("#000000");
			map.put("keyword5", t6);
			TemplateData t7 = new TemplateData();
			t7.setValue(order.getTotalPrice().toString());
			t7.setColor("#000000");
			map.put("keyword6", t7);
			TemplateData t8 = new TemplateData();
			t8.setValue(address.getPhone());
			t8.setColor("#000000");
			map.put("keyword7", t8);
			w.setData(map);
			String jsonTemplate = JSONObject.toJSON(w).toString();
			System.out.println(jsonTemplate);
			try {
				SendTemplateMessageUtil.send(jsonTemplate);
			} catch (Exception e) {
				// message += ",但距离支付完成超过七天将不发送";
			}
		/*******************************************/
		dataResult.setCode(Code.SUCCESS);
		dataResult.setMessage("确认订单成功");
		return JsonUtil.toJsonString(dataResult);
	}

	@RequestMapping(value = "/getUserOrder", method = RequestMethod.POST)
	public String getUserOrder(HttpServletRequest request, DiyOrder order, @RequestParam("page") Integer page,
			@RequestParam("count") Integer count) {
		DataResult dataResult = new DataResult(page, count);
		String userAuthingId = (String) SessionUtil.getAttr(request, SessionAttr.USERAUTHINGID);
		order.setUser(userAuthingId);
		dataResult.setData(diyOrderService.getDiyOrder(order, page, count));
		dataResult.setTotal(diyOrderService.countDiyOrder(order));
		dataResult.setCode(Code.SUCCESS);
		dataResult.setMessage("返回成功");
		return JsonUtil.toJsonString(dataResult);
	}

}
